package com.example.tongyao.utils;

import com.example.tongyao.system.service.ISysAttributeService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * tongyao >>> 【com.example.tongyao.utils】
 * 定时器
 *
 * @author: tongyao
 * @since: 2021-6-19 12:11
 */

//@Configuration
//@EnableScheduling //开启定时器
public class SchedulingUtils implements SchedulingConfigurer {

    @Resource
    private ISysAttributeService iSysAttributeService;

    Logger logger = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    /**
     * 执行灵活定时任务
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.addTriggerTask(
                //1.添加任务内容(Runnable)
                () -> timingMethed(),
                //2.设置执行周期(Trigger)
                triggerContext -> {
                    //2.1 从数据库获取执行周期
                    String cron = iSysAttributeService.byKeyGetValue("timing_rule").getValue();
                    //2.2 合法性校验.
                    if (StringUtils.isEmpty(cron)) {
                        // Omitted Code ..
                    }
                    //2.3 返回执行周期(Date)
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
        );
    }

    public void timingMethed(){
        logger.info("开始执行动态定时任务: " + LocalDateTime.now().toLocalTime());

        //错误示例：ApiController apiController = new ApiController();
        //不要使用new来调用Controller里面的方法，这样会导致本身Controller里面的方法@Value等注入失效为null
        //要使用@Resource来注入Controller，调用方法

        //logger.info(apiController.pushData());
    }

    /**
     * 定时时间不能灵活配置，定时规则来自properties
     */
    @Scheduled(cron = "${scheduling.timingTime}")
    public void timingScheduling(){
        logger.info("注解定时器-开始执行动态定时任务: " + LocalDateTime.now().toLocalTime());
    }

    /*下面是定时规则*/
    //Cron表达式范例：
    //每隔5秒执行一次：*/5 * * * * ?
    //每隔1分钟执行一次：0 */1 * * * ?
    //每天23点执行一次：0 0 23 * * ?
    //每天凌晨1点执行一次：0 0 1 * * ?
    //每月1号凌晨1点执行一次：0 0 1 1 * ?
    //每月最后一天23点执行一次：0 0 23 L * ?
    //每周星期天凌晨1点实行一次：0 0 1 ? * L
    //在26分、29分、33分执行一次：0 26,29,33 * * * ?
    //每天的0点、13点、18点、21点都执行一次：0 0 0,13,18,21 * * ?
}
